#include "market_data/market_data_monitor.h"
#include <cmath>

namespace hft {

MarketDataMonitor::MarketDataMonitor() = default;

void MarketDataMonitor::onMarketData(const MarketDataMessage& data) {
    std::lock_guard<std::mutex> lock(mutex_);
    
    auto& stats = statistics_[data.symbol];
    auto now = std::chrono::system_clock::now();
    
    // 检查数据延迟
    auto delay = std::chrono::duration_cast<std::chrono::milliseconds>(
        now - data.timestamp).count();
    updateDelayStats(data.symbol, delay);
    
    // 检查价格变化
    if (stats.last_price > 0) {
        stats.price_change_pct = std::abs(data.last_price - stats.last_price) / 
                                stats.last_price * 100.0;
    }
    stats.last_price = data.last_price;
    
    // 更新统计信息
    stats.last_update_time = now;
    stats.message_count++;
    
    // 检查异常
    if (!checkPriceAnomaly(data.symbol, data.last_price) ||
        !checkDataGap(data.symbol, data.timestamp)) {
        stats.error_count++;
        spdlog::warn("Market data anomaly detected for {}: price={}, delay={}ms", 
                    data.symbol, data.last_price, delay);
    }
}

MarketDataMonitor::Statistics MarketDataMonitor::getStatistics(
    const std::string& symbol) const {
    std::lock_guard<std::mutex> lock(mutex_);
    auto it = statistics_.find(symbol);
    if (it != statistics_.end()) {
        return it->second;
    }
    return Statistics{};
}

bool MarketDataMonitor::checkDataQuality(const std::string& symbol) const {
    std::lock_guard<std::mutex> lock(mutex_);
    auto it = statistics_.find(symbol);
    if (it == statistics_.end()) {
        return false;
    }
    
    const auto& stats = it->second;
    auto now = std::chrono::system_clock::now();
    
    // 检查各项指标
    bool quality_ok = true;
    
    // 1. 检查延迟
    if (stats.avg_delay_ms > MAX_DELAY_MS) {
        spdlog::warn("{}: High average delay: {}ms", symbol, stats.avg_delay_ms);
        quality_ok = false;
    }
    
    // 2. 检查数据断点
    auto time_since_last_update = std::chrono::duration_cast<std::chrono::seconds>(
        now - stats.last_update_time).count();
    if (time_since_last_update > MAX_GAP.count()) {
        spdlog::warn("{}: Data gap detected: {}s", symbol, time_since_last_update);
        quality_ok = false;
    }
    
    // 3. 检查错误率
    if (stats.message_count > 0) {
        double error_rate = static_cast<double>(stats.error_count) / 
                          stats.message_count * 100.0;
        if (error_rate > 5.0) {  // 5%错误率阈值
            spdlog::warn("{}: High error rate: {:.2f}%", symbol, error_rate);
            quality_ok = false;
        }
    }
    
    return quality_ok;
}

void MarketDataMonitor::resetStatistics(const std::string& symbol) {
    std::lock_guard<std::mutex> lock(mutex_);
    if (symbol.empty()) {
        statistics_.clear();
    } else {
        statistics_.erase(symbol);
    }
}

bool MarketDataMonitor::checkPriceAnomaly(
    const std::string& symbol, double price) const {
    auto it = statistics_.find(symbol);
    if (it == statistics_.end()) {
        return true;  // 首次接收数据，不检查
    }
    
    const auto& stats = it->second;
    if (stats.last_price > 0 && stats.price_change_pct > MAX_PRICE_CHANGE_PCT) {
        return false;  // 价格变化超过阈值
    }
    
    return true;
}

void MarketDataMonitor::updateDelayStats(
    const std::string& symbol, double delay_ms) {
    auto& stats = statistics_[symbol];
    
    // 更新最大延迟
    stats.max_delay_ms = std::max(stats.max_delay_ms, delay_ms);
    
    // 使用指数移动平均更新平均延迟
    const double alpha = 0.1;  // 平滑因子
    if (stats.avg_delay_ms == 0) {
        stats.avg_delay_ms = delay_ms;
    } else {
        stats.avg_delay_ms = alpha * delay_ms + (1 - alpha) * stats.avg_delay_ms;
    }
}

bool MarketDataMonitor::checkDataGap(
    const std::string& symbol,
    const std::chrono::system_clock::time_point& timestamp) const {
    auto it = statistics_.find(symbol);
    if (it == statistics_.end()) {
        return true;  // 首次接收数据，不检查
    }
    
    const auto& stats = it->second;
    auto gap = std::chrono::duration_cast<std::chrono::seconds>(
        timestamp - stats.last_update_time);
    
    return gap <= MAX_GAP;
}

} // namespace hft